import { error, warn } from "cc";

export enum HttpEvent {
    NO_NETWORK = "http_request_no_network", // 断网
    UNKNOWN_ERROR = "http_request_unknown_error", // 未知错误
    TIMEOUT = "http_request_timout", // 请求超时
}

const urls: any = {}; // 当前请求地址集合，主要用于重复请求
const requestParams: any = {}; // 请求参数
const HTTP_TIMEOUT: number = 10000; // 请求超时时间

export class HttpRequest {
    /**
     * HTTP GET请求
     * 例：
     * 
     * Get
        var complete = function(response){
            LogWrap.log(response);
        }
        var error = function(response){
            LogWrap.log(response);
        }
        this.get(name, complete, error);
    */
    public get(name: string, params: any) {
        return this.sendRequest(name, params, false);
    }

    public getByArraybuffer(name: string, params: any) {
        return this.sendRequest(name, params, false, "arraybuffer", false);
    }

    /** 
     * HTTP POST请求
     * 例：
     *      
     * Post
        var param = '{"LoginCode":"donggang_dev","Password":"e10adc3949ba59abbe56e057f20f883e"}'
        var complete = function(response){
                var jsonData = JSON.parse(response);
                var data = JSON.parse(jsonData.Data);
            LogWrap.log(data.Id);
        }
        var error = function(response){
            LogWrap.log(response);
        }
        this.post(name, param, complete, error);
    */
    public post(name: string, params: any) {
        return this.sendRequest(name, params, true);
    }

    /** 取消请求中的请求 */
    public abort(url: string) {
        var xhr = urls[url];
        if (xhr) {
            xhr.abort();
        }
    }

    /**
     * 获得字符串形式的参数
     */
    private getParamString(params: any) {
        var result = "";
        for (var name in params) {
            let data = params[name];
            if (data instanceof Object) {
                for (var key in data) result += `${key}=${data[key]}&`;
            } else {
                result += `${name}=${data}&`;
            }
        }

        return result.substr(0, result.length - 1);
    }

    /**
     * Http请求
     * @param name(string)              请求地址
     * @param params(JSON)              请求参数
     * @param isPost(boolen)            是否为POST方式
     * @param callback(function)        请求成功回调
     * @param errorCallback(function)   请求失败回调
     * @param responseType(string)      响应类型
     */
    private sendRequest(url: string, params: any, isPost: boolean, responseType?: string, isOpenTimeout = true, timeout: number = HTTP_TIMEOUT) {
        let newUrl: string, paramsStr: string;
        if (params) {
            paramsStr = this.getParamString(params);
            if (url.indexOf("?") > -1) newUrl = url + "&" + paramsStr;
            else newUrl = url + "?" + paramsStr;
        } else {
            newUrl = url;
        }

        if (urls[newUrl] != null && requestParams[newUrl] == paramsStr!) {
            warn(`地址【${url}】已正在请求中，不能重复请求`);
            return;
        }
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            if (isPost) {
                xhr.open("POST", url);
            } else {
                xhr.open("GET", newUrl);
            }

            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            var data: any = {};
            data.url = url;
            data.params = params;
            // 请求超时
            if (isOpenTimeout) {
                xhr.timeout = timeout;
                xhr.ontimeout = () => {
                    this.deleteCache(newUrl);
                    data.event = HttpEvent.TIMEOUT;
                    reject(data);
                };
            }

            xhr.onloadend = (a) => {
                if (xhr.status == 500) {
                    this.deleteCache(newUrl);
                    data.event = HttpEvent.NO_NETWORK; // 断网
                    reject(data);
                }
            };

            xhr.onerror = () => {
                this.deleteCache(newUrl);
                if (xhr.readyState == 0 || xhr.readyState == 1 || xhr.status == 0) {
                    data.event = HttpEvent.NO_NETWORK; // 断网
                } else {
                    data.event = HttpEvent.UNKNOWN_ERROR; // 未知错误
                }
                reject(data);
            };

            xhr.onreadystatechange = () => {
                if (xhr.readyState != 4) {
                    this.deleteCache(newUrl);
                    data.event = "xhr.readyState != 4";
                    reject(data);
                    return;
                }
                this.deleteCache(newUrl);
                if (xhr.status == 200) {
                    if (responseType == "arraybuffer") {
                        // 加载非文本格式
                        xhr.responseType = responseType;
                        resolve(xhr.response);
                    } else {
                        // 加载文本格式
                        var data: any = JSON.parse(xhr.response);
                        resolve(data);
                    }
                }
            };

            urls[newUrl] = xhr;
            requestParams[newUrl] = paramsStr!;

            if (params == null || params == "") {
                xhr.send();
            } else {
                xhr.send(paramsStr!); // 根据服务器接受数据方式做选择
            }
        });
    }

    private deleteCache(url: string) {
        delete urls[url];
        delete requestParams[url];
    }
}
